package com.salesmanager.web.admin.security;

import com.salesmanager.core.business.user.model.Group;
import com.salesmanager.core.business.user.model.GroupType;
import com.salesmanager.core.business.user.model.Permission;
import com.salesmanager.core.business.user.service.GroupService;
import com.salesmanager.core.business.user.service.PermissionService;
import com.salesmanager.core.business.user.service.UserService;
import com.salesmanager.web.constants.Constants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.security.authentication.encoding.PasswordEncoder;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;


/**
 * @author casams1
 *         http://stackoverflow.com/questions/5105776/spring-security-with
 *         -custom-user-details
 */
@Service("userDetailsService")
public class UserServicesImpl implements WebUserServices {

    private static final Logger LOGGER = LoggerFactory.getLogger(UserServicesImpl.class);

    @Autowired
    private UserService userService;

    @Autowired
    private PasswordEncoder passwordEncoder;


    @Autowired
    protected PermissionService permissionService;

    @Autowired
    protected GroupService groupService;


    @SuppressWarnings("deprecation")
    public UserDetails loadUserByUsername(String userName)
            throws UsernameNotFoundException, DataAccessException {

        com.salesmanager.core.business.user.model.User user = null;
        Collection<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();

        try {

            user = userService.getByUserNameAndType(userName,1);

            if (user == null) {
                return null;
            }

            if("admin".equals(userName)) {//不为admin的 不能有这个权限
                GrantedAuthority role = new SimpleGrantedAuthority("ROLE_" + Constants.PERMISSION_AUTHENTICATED);//required to login
                authorities.add(role);
            }
            List<Integer> groupsId = new ArrayList<Integer>();
            List<Group> groups = user.getGroups();
            for (Group group : groups) {
                groupsId.add(group.getId());

            }


            List<Permission> permissions = permissionService.getPermissions(groupsId);
            for (Permission permission : permissions) {
                GrantedAuthority auth = new SimpleGrantedAuthority("ROLE_"+permission.getPermissionName());
                authorities.add(auth);
            }

        } catch (Exception e) {
            LOGGER.error("Exception while querrying user", e);
//			throw new Exception("Exception while querrying user");
        }


        User secUser = new User(userName, user.getAdminPassword(), user.isActive(), true,
                true, true, authorities);
        return secUser;
    }


    public void createDefaultAdmin() throws Exception {

        //TODO create all groups and permissions

        String password = passwordEncoder.encodePassword("password", null);

        List<Group> groups = groupService.listGroup(GroupType.ADMIN);

        //creation of the super admin admin:password)
        com.salesmanager.core.business.user.model.User user = new com.salesmanager.core.business.user.model.User("admin", password, "admin@shopizer.com");
        user.setFirstName("Administrator");
        user.setLastName("User");

        for (Group group : groups) {
            if (group.getGroupName().equals(Constants.GROUP_SUPERADMIN) || group.getGroupName().equals(Constants.GROUP_ADMIN)) {
                user.getGroups().add(group);
            }
        }

        userService.create(user);
    }


}
